#include "ClipPathViewStackNode.h"
#include "RNOH/arkui/NativeNodeApi.h"
#include <memory>
#include "RectF.h"
#include "SVGViewBox.h"
#include "glog/logging.h"
// #include "SVGPathParser.h"
// #include "Point.h"

namespace rnoh {
    ClipPathViewStackNode::ClipPathViewStackNode()
        : ArkUINode(NativeNodeApi::getInstance()->createNode(ArkUI_NodeType::ARKUI_NODE_STACK)) {
    }

    void ClipPathViewStackNode::insertChild(ArkUINode &child, std::size_t index) {
        maybeThrow(NativeNodeApi::getInstance()->addChild(m_nodeHandle, child.getArkUINodeHandle()));
    }

    void ClipPathViewStackNode::removeChild(ArkUINode &child) {
        maybeThrow(NativeNodeApi::getInstance()->removeChild(m_nodeHandle, child.getArkUINodeHandle()));
    }
    ClipPathViewStackNode &ClipPathViewStackNode::setD(const std::string &D) {
//         if(D.empty()){
//          return *this;
//         }
//         SVGPathParser::mScale = this->getDensity();
//         SVGPathParser::parse(D.c_str());
//         ArkUI_NumberValue startPosition[] = {{.f32 = SVGPathParser::mX},{.f32 = SVGPathParser::mY}};
//         ArkUI_AttributeItem positionItem = {startPosition, sizeof(startPosition) / sizeof(ArkUI_NumberValue)};
//         LOG(INFO) << "[clx] <ClipPathViewStackNode::setD> positionItem: " << &positionItem;
//         maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_POSITION, &positionItem));
//         rnoh::RectF *ptr = nullptr;
//         if(ptr != nullptr && SVGPathParser::mArcRect.width() == SVGPathParser::mArcRect.height()){
//          ArkUI_NumberValue arcValue[] = {{ArkUI_ClipType::ARKUI_CLIP_TYPE_CIRCLE},{.f32 = SVGPathParser::mArcRect.width()},
//                                          {.f32 = SVGPathParser::mArcRect.height()}};
//          ArkUI_AttributeItem arcItem = {arcValue, sizeof(arcValue) / sizeof(ArkUI_NumberValue)};
//          LOG(INFO) << "[clx] <ClipPathViewStackNode::setD> arcItem: " << &arcItem;
//          maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CLIP_SHAPE, &arcItem));
//         }
//         if(ptr != nullptr && SVGPathParser::mArcRect.width() != SVGPathParser::mArcRect.height()){
//          ArkUI_NumberValue arcValue[] = {{ArkUI_ClipType::ARKUI_CLIP_TYPE_ELLIPSE},{.f32 = SVGPathParser::mArcRect.width()},
//                                          {.f32 = SVGPathParser::mArcRect.height()}};
//          ArkUI_AttributeItem arcItem = {arcValue, sizeof(arcValue) / sizeof(ArkUI_NumberValue)};
//          LOG(INFO) << "[clx] <ClipPathViewStackNode::setD> arcItem: " << &arcItem;
//          maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CLIP_SHAPE, &arcItem));
//         }
//         if(!SVGPathParser::mPoints.empty()){
//           if(SVGPathParser::mPoints.size() == 3){
//               float width = SVGPathParser::mPoints[0].x-SVGPathParser::mX;
//               float height = SVGPathParser::mPoints[1].y-SVGPathParser::mY;
//               ArkUI_NumberValue recValue[] = {{ArkUI_ClipType::ARKUI_CLIP_TYPE_RECTANGLE},
//                                               {.f32 = width},
//                                               {.f32 = height},{0.f},{0.f}};
//               ArkUI_AttributeItem recItem = {recValue, sizeof(recValue) / sizeof(ArkUI_NumberValue)};
//               LOG(INFO) << "[clx] <ClipPathViewStackNode::setD> recItem: " << &recItem;
//               maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CLIP_SHAPE, &recItem));
//           }
//           if (SVGPathParser::mPoints.size() == 1){
//               float width = SVGPathParser::mPoints[0].x - SVGPathParser::mX;
//               float height = SVGPathParser::mPoints[0].y - SVGPathParser::mY;
//               ArkUI_NumberValue pathValue[] = {
//                   {ArkUI_ClipType::ARKUI_CLIP_TYPE_PATH}, {.f32 = width}, {.f32 = height}};
//               ArkUI_AttributeItem pathItem = {pathValue, sizeof(pathValue) / sizeof(ArkUI_NumberValue)};
//               LOG(INFO) << "[clx] <ClipPathViewStackNode::setD> pathItem: " << &pathItem;
//               maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CLIP_SHAPE, &pathItem));
//           }
//         }
        return *this;
    }
    ClipPathViewStackNode &ClipPathViewStackNode::setOpacity(const float &Opacity) {
        ArkUI_NumberValue indexValue[] = {{.f32 = Opacity}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setOpacity> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_OPACITY, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setMask(const std::string &Mask) {
        ArkUI_AttributeItem indexItem = {.string = Mask.c_str()};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setMask> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_MASK, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setOldMask(const std::string &OldMask) {
        ArkUI_AttributeItem indexItem = {.string = OldMask.c_str()};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setOldMask> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_MARK_ANCHOR, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setFillColor(const int &FillColor) {
        ArkUI_NumberValue indexValue[] = {{.i32 = FillColor}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setFillColor> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_BACKGROUND_COLOR, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setFillOpacity(const float &FillOpacity) {
        ArkUI_NumberValue indexValue[] = {{.f32 = FillOpacity}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setFillOpacity> indexItem: " << &indexItem;
        // maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, , &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setFillRule(const std::string &FillRule) {
        ArkUI_AttributeItem indexItem = {.string = FillRule.c_str()};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setFillRule> indexItem: " << &indexItem;
        // maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, , &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeColor(const int &strokeColor) {
        ArkUI_NumberValue indexValue[] = {{.i32 = strokeColor}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeColor> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_BORDER_COLOR, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeOpacity(const float &StrokeOpacity) {
        ArkUI_NumberValue indexValue[] = {{.f32 = StrokeOpacity}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeOpacity> indexItem: " << &indexItem;
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeWidth(const float &StrokeWidth) {
        ArkUI_NumberValue indexValue[] = {{.f32 = StrokeWidth}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeWidth> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_BORDER_WIDTH, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeCap(const std::string &StrokeCap) {
        ArkUI_AttributeItem indexItem = {.string = StrokeCap.c_str()};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeCap> indexItem: " << &indexItem;
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeJoin(const std::string &StrokeJoin) {
        ArkUI_AttributeItem indexItem = {.string = StrokeJoin.c_str()};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeJoin> indexItem: " << &indexItem;
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeMiter(const float &StrokeMiter) {
        ArkUI_NumberValue indexValue[] = {{.f32 = StrokeMiter}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeMiter> indexItem: " << &indexItem;
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeStart(const float &StrokeStart) {
        ArkUI_NumberValue indexValue[] = {{.f32 = StrokeStart}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeStart> indexItem: " << &indexItem;
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setStrokeEnd(const float &StrokeEnd) {
        ArkUI_NumberValue indexValue[] = {{.f32 = StrokeEnd}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setStrokeEnd> indexItem: " << &indexItem;
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setShadowColor(const int &shadowColor) {
        ArkUI_NumberValue indexValue[] = {{.f32 = this->shadowRadius},
                                          0,
                                          {.f32 = this->shadowOffsetX},
                                          {.f32 = this->shadowOffsetY},
                                          ARKUI_SHADOW_TYPE_COLOR,
                                          {.i32 = shadowColor},
                                          0};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setShadowColor> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CUSTOM_SHADOW, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setShadowOpacity(const float &shadowOpacity) {
        ArkUI_NumberValue indexValue[] = {{.f32 = this->shadowRadius},
                                          0,
                                          {.f32 = this->shadowOffsetX},
                                          {.f32 = this->shadowOffsetY},
                                          ARKUI_SHADOW_TYPE_COLOR,
                                          {.u32 = this->shadowColor},
                                          0};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setShadowOpacity> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CUSTOM_SHADOW, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setShadowRadius(const float &shadowRadius) {
        ArkUI_NumberValue indexValue[] = {{.f32 = shadowRadius},
                                          0,
                                          {.f32 = this->shadowOffsetX},
                                          {.f32 = this->shadowOffsetY},
                                          ARKUI_SHADOW_TYPE_COLOR,
                                          {.u32 = this->shadowColor},
                                          0};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setShadowRadius> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CUSTOM_SHADOW, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setShadowOffsetX(const float &shadowOffsetX) {
        ArkUI_NumberValue indexValue[] = {{.f32 = this->shadowRadius},
                                          0,
                                          {.f32 = shadowOffsetX},
                                          {.f32 = this->shadowOffsetY},
                                          ARKUI_SHADOW_TYPE_COLOR,
                                          {.u32 = this->shadowColor},
                                          0};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setShadowOffsetX> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CUSTOM_SHADOW, &indexItem));
        return *this;
    }
    ClipPathViewStackNode &ClipPathViewStackNode::setShadowOffsetY(const float &shadowOffsetY) {
        ArkUI_NumberValue indexValue[] = {{.f32 = this->shadowRadius},
                                          0,
                                          {.f32 = this->shadowOffsetX},
                                          {.f32 = shadowOffsetY},
                                          ARKUI_SHADOW_TYPE_COLOR,
                                          {.u32 = this->shadowColor},
                                          0};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setShadowOffsetY> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CUSTOM_SHADOW, &indexItem));
        return *this;
    }
    ClipPathViewStackNode &ClipPathViewStackNode::setShadowOffsetIsPercent(const bool &shadowOffsetIsPercent) {
        ArkUI_NumberValue indexValue[] = {{static_cast<float>(shadowOffsetIsPercent)}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setShadowOffsetIsPercent> indexItem: " << &indexItem;
        // maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_CUSTOM_SHADOW, &indexItem));
        return *this;
    }

    ClipPathViewStackNode &ClipPathViewStackNode::setBgColor(const int &bgColor) {
        ArkUI_NumberValue indexValue[] = {{.i32 = bgColor}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setBgColor> indexItem: " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_BACKGROUND_COLOR, &indexItem));
        return *this;
    }

    bool ClipPathViewStackNode::validateViewBox() { return rectFVb.width() >= 0.f && rectFVb.height() >= 0.f; }

    float ClipPathViewStackNode::toDip(float value) {
        DisplayMetrics metrics(getDensity()); 
        float valueInDip = TypedValue::applyDimension(TypedValue::COMPLEX_UNIT_DIP, value, metrics);
        return valueInDip;
    }

    void ClipPathViewStackNode::transform() {
        const ArkUI_AttributeItem *widthItem = NativeNodeApi::getInstance()->getAttribute(m_nodeHandle, NODE_WIDTH);
        const ArkUI_AttributeItem *heightItem = NativeNodeApi::getInstance()->getAttribute(m_nodeHandle, NODE_HEIGHT);
        // translation
        if (this->translationX != 0.f || this->translationY != 0.f) {
            float transX;
            float transY;
            if (this->translationIsPercent) {
                LOG(WARNING) << "[clx] <ClipPathViewStackNode::translation::widthItem " << &widthItem;
                LOG(WARNING) << "[clx] <ClipPathViewStackNode::translation::heightItem " << &heightItem;
                if (widthItem && heightItem) {
                    transX = (this->translationX * widthItem->value[0].f32);
                    transY = (this->translationY * heightItem->value[0].f32);
                }
            } else if (validateViewBox()) {
                transX = this->translationX / rectFVb.width() * rectF.width();
                transY = this->translationY / rectFVb.height() * rectF.height();
            } else {
                transX = toDip(this->translationX);
                transY = toDip(this->translationY);
            }
            // TODO 以获取scale  可用全区vector  存储
            ArkUI_NumberValue indexValue[] = {{.f32 = this->translationX}, {.f32 = this->translationY}, 0.f};
            ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
            LOG(WARNING) << "[clx] <ClipPathViewStackNode::translation> indexItem: " << &indexItem;
            maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_TRANSLATE, &indexItem));
            // mMatrix.postScale(this->scaleOriginX, this->scaleOriginY, transX, transY);
        }
        // 旋转
        if (this->rotation != 0.f) {
            float rotX;
            float rotY;
            if (this->rotationIsPercent) {
                LOG(WARNING) << "[clx] <ClipPathViewStackNode::rotation::widthItem " << &widthItem;
                LOG(WARNING) << "[clx] <ClipPathViewStackNode::rotation::heightItem " << &heightItem;
                if (widthItem && heightItem) {
                    rotX = (this->rotationOx * widthItem->value[0].f32);
                    rotY = (this->rotationOy * heightItem->value[0].f32);
                }
            } else if (validateViewBox()) {
                rotX = rectF.left + modUtil.viewBoxToWidth(this->rotationOx, rectFVb, rectF.width());
                rotY = rectF.top + modUtil.viewBoxToHeight(this->rotationOy, rectFVb, rectF.height());
            } else {
                rotX = toDip(this->rotationOx);
                rotY = toDip(this->rotationOy);
            }
            // TODO get rote  vector  save
            ArkUI_NumberValue indexValue[] = {
                {.f32 = this->rotationOx}, {.f32 = this->rotationOx}, 0.f, {.f32 = this->rotation}, 0.0f};
            ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
            LOG(WARNING) << "[clx] <ClipPathViewStackNode::rote> indexItem: " << &indexItem;
            maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_ROTATE, &indexItem));
        }
        // 缩放
        if (this->scaleX != 1.f || this->scaleY != 1.f) {
            float oX;
            float oY;
            if (this->scaleIsPercent) {
                LOG(WARNING) << "[clx] <ClipPathViewStackNode::scale::widthItem " << &widthItem;
                LOG(WARNING) << "[clx] <ClipPathViewStackNode::scale::heightItem " << &heightItem;
                if (widthItem && heightItem) {
                    oX = (this->scaleOriginX * widthItem->value[0].f32);
                    oY = (this->scaleOriginY * heightItem->value[0].f32);
                }
            } else if (validateViewBox()) {
                oX = rectF.left + modUtil.viewBoxToWidth(this->scaleOriginX, rectFVb, rectF.width());
                oY = rectF.top + modUtil.viewBoxToHeight(this->scaleOriginY, rectFVb, rectF.height());
            } else {
                oX = toDip(this->scaleOriginX);
                oY = toDip(this->scaleOriginY);
            }
            // TODO get rote  vector  save
            ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleOriginX}, {.f32 = this->scaleOriginY}};
            ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
            LOG(WARNING) << "[clx] <ClipPathViewStackNode::scale> indexItem: " << &indexItem;
            maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
        }
    }

    void ClipPathViewStackNode::setSc(float v) {
        if (this->scaleX == v && this->scaleY == v) {
            return;
        }
        this->scaleX = v;
        this->scaleY = v;
        ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleX}, {.f32 = this->scaleY}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setSc>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
    }

    void ClipPathViewStackNode::setScX(float v) {
        if (this->scaleX == v) {
            return;
        }
        this->scaleX = v;
        ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleX}, {.f32 = this->scaleY}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setScX>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
    }

    void ClipPathViewStackNode::setScY(float v) {
        if (this->scaleY == v) {
            return;
        }
        this->scaleY = v;
        ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleX}, {.f32 = this->scaleY}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setScY>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
    }

    void ClipPathViewStackNode::setScO(float v) {
        if (this->scaleOriginX == v && this->scaleOriginY == v) {
            return;
        }
        this->scaleOriginX = v;
        this->scaleOriginY = v;
        ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleOriginX}, {.f32 = this->scaleOriginY}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setScO>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
    }

    void ClipPathViewStackNode::setScOx(float v) {
        if (this->scaleOriginX == v) {
            return;
        }
        this->scaleOriginX = v;
        ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleOriginX}, {.f32 = this->scaleOriginY}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setScOx>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
    }

    void ClipPathViewStackNode::setScOy(float v) {
        if (this->scaleOriginY == v) {
            return;
        }
        this->scaleOriginY = v;
        ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleOriginX}, {.f32 = this->scaleOriginY}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setScOy>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
    }

    void ClipPathViewStackNode::setScPercentageValue(bool v) {
        if (this->scaleIsPercent == v) {
            return;
        }
        this->scaleIsPercent = v;
        this->transform();
        ArkUI_NumberValue indexValue[] = {{.f32 = this->scaleOriginX}, {.f32 = this->scaleOriginY}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setScPercentageValue>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_SCALE, &indexItem));
    }

    void ClipPathViewStackNode::setTransX(float v) {
        if (this->translationX == v) {
            return;
        }
        this->translationX = v;
        ArkUI_NumberValue indexValue[] = {
            {static_cast<float>(this->translationX)}, {static_cast<float>(this->translationY)}, {0.0f}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setTransX>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_TRANSLATE, &indexItem));
    }

    void ClipPathViewStackNode::setTransY(float v) {
        if (this->translationY == v) {
            return;
        }
        this->translationY = v;
        ArkUI_NumberValue indexValue[] = {
            {static_cast<float>(this->translationX)}, {static_cast<float>(this->translationY)}, {0.0f}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setTransY>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_TRANSLATE, &indexItem));
    }

    void ClipPathViewStackNode::setTransPercentageValue(bool v) {
        if (this->translationIsPercent == v) {
            return;
        }
        this->translationIsPercent = v;
        this->transform();
        ArkUI_NumberValue indexValue[] = {
            {static_cast<float>(this->translationX)}, {static_cast<float>(this->translationY)}, {0.0f}};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setTransPercentageValue>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_TRANSLATE, &indexItem));
    }

    void ClipPathViewStackNode::setRot(float v) {
        if (this->rotation == v) {
            return;
        }
        this->rotation = v;
        ArkUI_NumberValue indexValue[] = {
            {.f32 = this->rotationOx}, {.f32 = this->rotationOy}, 0.0f, {.f32 = this->rotation}, 0.0f};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setRot> " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_ROTATE, &indexItem));
    }

    void ClipPathViewStackNode::setRotO(float v) {
        if (this->rotationOx == v && this->rotationOy == v) {
            return;
        }
        this->rotationOx = v;
        this->rotationOy = v;
        ArkUI_NumberValue indexValue[] = {
            {.f32 = this->rotationOx}, {.f32 = this->rotationOy}, 0.0f, {.f32 = this->rotation}, 0.0f};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setRotO>" << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_ROTATE, &indexItem));
    }

    void ClipPathViewStackNode::setRotOx(float v) {
        if (this->rotationOx == v) {
            return;
        }
        this->rotationOx = v;
        ArkUI_NumberValue indexValue[] = {
            {.f32 = this->rotationOx}, {.f32 = this->rotationOy}, 0.0f, {.f32 = this->rotation}, 0.0f};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setRotOx> " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_ROTATE, &indexItem));
    }

    void ClipPathViewStackNode::setRotOy(float v) {
        if (this->rotationOy == v) {
            return;
        }
        this->rotationOy = v;
        ArkUI_NumberValue indexValue[] = {
            {.f32 = this->rotationOx}, {.f32 = this->rotationOy}, 0.0f, {.f32 = this->rotation}, 0.0f};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::setRotOy> " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_ROTATE, &indexItem));
    }


    void ClipPathViewStackNode::setRotPercentageValue(bool v) {
        if (this->rotationIsPercent == v) {
            return;
        }
        this->rotationIsPercent = v;
        this->transform();
        ArkUI_NumberValue indexValue[] = {
            {.f32 = this->rotationOx}, {.f32 = this->rotationOy}, 0.0f, {.f32 = this->rotation}, 0.0f};
        ArkUI_AttributeItem indexItem = {indexValue, sizeof(indexValue) / sizeof(ArkUI_NumberValue)};
        LOG(WARNING) << "[clx] <ClipPathViewStackNode::rotationIsPercent> " << &indexItem;
        maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_ROTATE, &indexItem));
    }
    void ClipPathViewStackNode::setAlign(std::string align) {
        if (this->align == align) {
            return;
        }
        this->align = align;
        std::vector<float> transformResult = rnoh::SVGViewBox::transform(rectFVb, rectF, this->align, 0, getDensity());
        setScX(transformResult[0]);
        setScY(transformResult[1]);
        setTransX(transformResult[2]);
        setTransY(transformResult[3]);
    }

    float ClipPathViewStackNode::getDensity() { return 2.5f; }
    void ClipPathViewStackNode::setViewBox(float viewBox[4]) {
        float density = getDensity();
        rectFVb.set(viewBox[0], viewBox[1], (viewBox[0] + viewBox[2]), (viewBox[1] + viewBox[3]));
        rectFVbDensity.set(viewBox[0] * density, viewBox[1] * density, (viewBox[0] + viewBox[2]) * density,
                           (viewBox[1] + viewBox[3]) * density);
    }

} // namespace rnoh
